From fea77823212ce8b48b1897cb73dd0590896809eb Mon Sep 17 00:00:00 2001 From: "emellor@leeni.uk.xensource.com" Date: Sun, 23 Oct 2005 22:45:15 +0100 Subject: [PATCH] Change the semantics of GetDomainPath so that it always succeeds, regardless of whether a domain has been introduced to the store. Added a separate message XS_IS_DOMAIN_INTRODUCED and API for that (xs_is_domain_introduced) to determine whether the domain has really been introduced. This change means that the tools can determine the correct domain path earlier in the domain creation process, which is particularly a factor with live migration, as it allows us to create the devices earlier in the process, and unpause the new domain before performing the introduce. Until recently we already had these features, but the simplification of the interface between xend and xenstored caused breakage. No longer clear out the domain path when a domain is introduced -- this was a hack to work around the recent problematic semantics of GetDomainPath. Do not write the contents of the info block to the store. All the configuration info is written to the /vm path, and anything else in the info block is either dealt with explicitly or is ephemeral and has no place in the store. Signed-off-by: Ewan Mellor --- tools/console/daemon/io.c | 3 -- tools/python/xen/lowlevel/xs/xs.c | 3 +- tools/python/xen/xend/XendCheckpoint.py | 2 ++ tools/python/xen/xend/XendDomainInfo.py | 36 +++++++++++------------ tools/xenstore/xenstored_core.c | 15 ++++------ tools/xenstore/xenstored_core.h | 3 -- tools/xenstore/xenstored_domain.c | 39 +++++++++++++++++-------- tools/xenstore/xenstored_domain.h | 3 ++ tools/xenstore/xs.c | 17 +++++++++-- tools/xenstore/xs.h | 4 +++ xen/include/public/io/xs_wire.h | 1 + 11 files changed, 75 insertions(+), 51 deletions(-) diff --git a/tools/console/daemon/io.c b/tools/console/daemon/io.c index 9039a96525..60e89267fc 100644 --- a/tools/console/daemon/io.c +++ b/tools/console/daemon/io.c @@ -301,10 +301,7 @@ static struct domain *create_domain(int domid) } dom->domid = domid; - dom->conspath = xs_get_domain_path(xs, dom->domid); - if (dom->conspath == NULL) - goto out; s = realloc(dom->conspath, strlen(dom->conspath) + strlen("/console") + 1); if (s == NULL) diff --git a/tools/python/xen/lowlevel/xs/xs.c b/tools/python/xen/lowlevel/xs/xs.c index b5ce2c357b..1f0dd5fac2 100644 --- a/tools/python/xen/lowlevel/xs/xs.c +++ b/tools/python/xen/lowlevel/xs/xs.c @@ -795,11 +795,10 @@ static PyObject *xspy_close(PyObject *self, PyObject *args, PyObject *kwds) } #define xspy_get_domain_path_doc "\n" \ - "Return store path of domain.\n" \ + "Return store path of domain, whether or not the domain exists.\n" \ " domid [int]: domain id\n" \ "\n" \ "Returns: [string] domain store path.\n" \ - " None if domid doesn't exist.\n" \ "Raises RuntimeError on error.\n" \ "\n" diff --git a/tools/python/xen/xend/XendCheckpoint.py b/tools/python/xen/xend/XendCheckpoint.py index 828fd0f2eb..4455734952 100644 --- a/tools/python/xen/xend/XendCheckpoint.py +++ b/tools/python/xen/xend/XendCheckpoint.py @@ -144,6 +144,8 @@ def restore(xd, fd): if handler.store_mfn is None or handler.console_mfn is None: raise XendError('Could not read store/console MFN') + dominfo.unpause() + dominfo.completeRestore(handler.store_mfn, handler.console_mfn) return dominfo diff --git a/tools/python/xen/xend/XendDomainInfo.py b/tools/python/xen/xend/XendDomainInfo.py index 061e7863d5..11256f8916 100644 --- a/tools/python/xen/xend/XendDomainInfo.py +++ b/tools/python/xen/xend/XendDomainInfo.py @@ -198,7 +198,7 @@ def recreate(xeninfo, priv): vm = XendDomainInfo(xeninfo, domid, dompath, True) except Exception, exn: - if True: + if priv: log.warn(str(exn)) vm = XendDomainInfo(xeninfo, domid, dompath, True) @@ -223,7 +223,9 @@ def restore(config): try: vm.construct() vm.storeVmDetails() + vm.createDevices() vm.createChannels() + vm.storeDomDetails() return vm except: vm.destroy() @@ -337,8 +339,8 @@ def dom_get(dom): log.debug("domain_getinfo(%d) failed, ignoring: %s", dom, str(err)) return None -class XendDomainInfo: +class XendDomainInfo: def __init__(self, info, domid = None, dompath = None, augment = False): @@ -558,13 +560,13 @@ class XendDomainInfo: def completeRestore(self, store_mfn, console_mfn): + log.debug("XendDomainInfo.completeRestore") + self.store_mfn = store_mfn self.console_mfn = console_mfn self.introduceDomain() - self.create_devices() self.storeDomDetails() - self.unpause() self.refreshShutdown() @@ -597,10 +599,6 @@ class XendDomainInfo: 'memory/target': str(self.info['memory_KiB']) } - for (k, v) in self.info.items(): - if v: - to_store[k] = str(v) - def f(n, v): if v is not None: to_store[n] = str(v) @@ -1055,6 +1053,10 @@ class XendDomainInfo: raise VmError('Creating domain failed: name=%s' % self.info['name']) + self.dompath = GetDomainPath(self.domid) + + self.removeDom() + # Set maximum number of vcpus in domain xc.domain_max_vcpus(self.domid, int(self.info['vcpus'])) @@ -1065,8 +1067,6 @@ class XendDomainInfo: assert self.store_port is not None IntroduceDomain(self.domid, self.store_mfn, self.store_port) - self.dompath = GetDomainPath(self.domid) - assert self.dompath def initDomain(self): @@ -1105,7 +1105,7 @@ class XendDomainInfo: self.introduceDomain() - self.create_devices() + self.createDevices() self.info['start_time'] = time.time() @@ -1209,23 +1209,21 @@ class XendDomainInfo: raise - def create_configured_devices(self): - for (n, c) in self.info['device']: - self.createDevice(n, c) - + ## public: - def create_devices(self): + def createDevices(self): """Create the devices for a vm. @raise: VmError for invalid devices """ - self.create_configured_devices() + + for (n, c) in self.info['device']: + self.createDevice(n, c) + if self.image: self.image.createDeviceModel() - ## public: - def device_create(self, dev_config): """Create a new device. diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c index d9ecefc133..f5b1b014e3 100644 --- a/tools/xenstore/xenstored_core.c +++ b/tools/xenstore/xenstored_core.c @@ -166,6 +166,7 @@ static char *sockmsg_string(enum xsd_sockmsg_type type) case XS_SET_PERMS: return "SET_PERMS"; case XS_WATCH_EVENT: return "WATCH_EVENT"; case XS_ERROR: return "ERROR"; + case XS_IS_DOMAIN_INTRODUCED: return "XS_IS_DOMAIN_INTRODUCED"; default: return "**UNKNOWN**"; } @@ -1001,16 +1002,6 @@ static void do_rm(struct connection *conn, const char *name) } -void internal_rm(const char *name) -{ - struct node *node = read_node(NULL, name); - if (!node) { - return; - } - _rm(NULL, node, name); -} - - static void do_get_perms(struct connection *conn, const char *name) { struct node *node; @@ -1153,6 +1144,10 @@ static void process_message(struct connection *conn, struct buffered_data *in) do_introduce(conn, in); break; + case XS_IS_DOMAIN_INTRODUCED: + do_is_domain_introduced(conn, onearg(in)); + break; + case XS_RELEASE: do_release(conn, onearg(in)); break; diff --git a/tools/xenstore/xenstored_core.h b/tools/xenstore/xenstored_core.h index abcb42c38d..da98a9211d 100644 --- a/tools/xenstore/xenstored_core.h +++ b/tools/xenstore/xenstored_core.h @@ -155,9 +155,6 @@ void __attribute__((noreturn)) corrupt(struct connection *conn, struct connection *new_connection(connwritefn_t *write, connreadfn_t *read); -void internal_rm(const char *name); - - /* Is this a valid node name? */ bool is_valid_nodename(const char *node); diff --git a/tools/xenstore/xenstored_domain.c b/tools/xenstore/xenstored_domain.c index 69e429ccfa..d252469617 100644 --- a/tools/xenstore/xenstored_domain.c +++ b/tools/xenstore/xenstored_domain.c @@ -250,6 +250,11 @@ bool domain_can_write(struct connection *conn) return ((intf->rsp_prod - intf->rsp_cons) != XENSTORE_RING_SIZE); } +static char *talloc_domain_path(void *context, unsigned int domid) +{ + return talloc_asprintf(context, "/local/domain/%u", domid); +} + static struct domain *new_domain(void *context, unsigned int domid, unsigned long mfn, int port) { @@ -262,7 +267,7 @@ static struct domain *new_domain(void *context, unsigned int domid, domain->port = 0; domain->shutdown = 0; domain->domid = domid; - domain->path = talloc_asprintf(domain, "/local/domain/%d", domid); + domain->path = talloc_domain_path(domain, domid); domain->interface = xc_map_foreign_range( *xc_handle, domain->domid, getpagesize(), PROT_READ|PROT_WRITE, mfn); @@ -272,8 +277,6 @@ static struct domain *new_domain(void *context, unsigned int domid, list_add(&domain->list, &domains); talloc_set_destructor(domain, destroy_domain); - internal_rm(domain->path); - /* Tell kernel we're interested in this event. */ bind.remote_domain = domid; bind.remote_port = port; @@ -403,25 +406,37 @@ void do_release(struct connection *conn, const char *domid_str) void do_get_domain_path(struct connection *conn, const char *domid_str) { - struct domain *domain; - unsigned int domid; + char *path; if (!domid_str) { send_error(conn, EINVAL); return; } + path = talloc_domain_path(conn, atoi(domid_str)); + + send_reply(conn, XS_GET_DOMAIN_PATH, path, strlen(path) + 1); + + talloc_free(path); +} + +void do_is_domain_introduced(struct connection *conn, const char *domid_str) +{ + int result; + unsigned int domid; + + if (!domid_str) { + send_error(conn, EINVAL); + return; + } + domid = atoi(domid_str); if (domid == DOMID_SELF) - domain = conn->domain; + result = 1; else - domain = find_domain_by_domid(domid); + result = (find_domain_by_domid(domid) != NULL); - if (!domain) - send_error(conn, ENOENT); - else - send_reply(conn, XS_GET_DOMAIN_PATH, domain->path, - strlen(domain->path) + 1); + send_reply(conn, XS_IS_DOMAIN_INTRODUCED, result ? "T" : "F", 2); } static int close_xc_handle(void *_handle) diff --git a/tools/xenstore/xenstored_domain.h b/tools/xenstore/xenstored_domain.h index e8d5ec8c88..b8d839d624 100644 --- a/tools/xenstore/xenstored_domain.h +++ b/tools/xenstore/xenstored_domain.h @@ -25,6 +25,9 @@ void handle_event(void); /* domid, mfn, eventchn, path */ void do_introduce(struct connection *conn, struct buffered_data *in); +/* domid */ +void do_is_domain_introduced(struct connection *conn, const char *domid_str); + /* domid */ void do_release(struct connection *conn, const char *domid_str); diff --git a/tools/xenstore/xs.c b/tools/xenstore/xs.c index 22710d5d01..a817a88077 100644 --- a/tools/xenstore/xs.c +++ b/tools/xenstore/xs.c @@ -696,13 +696,20 @@ bool xs_introduce_domain(struct xs_handle *h, ARRAY_SIZE(iov), NULL)); } -bool xs_release_domain(struct xs_handle *h, unsigned int domid) +static void * single_with_domid(struct xs_handle *h, + enum xsd_sockmsg_type type, + unsigned int domid) { char domid_str[MAX_STRLEN(domid)]; sprintf(domid_str, "%u", domid); - return xs_bool(xs_single(h, NULL, XS_RELEASE, domid_str, NULL)); + return xs_single(h, NULL, type, domid_str, NULL); +} + +bool xs_release_domain(struct xs_handle *h, unsigned int domid) +{ + return xs_bool(single_with_domid(h, XS_RELEASE, domid)); } char *xs_get_domain_path(struct xs_handle *h, unsigned int domid) @@ -714,6 +721,12 @@ char *xs_get_domain_path(struct xs_handle *h, unsigned int domid) return xs_single(h, NULL, XS_GET_DOMAIN_PATH, domid_str, NULL); } +bool xs_is_domain_introduced(struct xs_handle *h, unsigned int domid) +{ + return strcmp("F", + single_with_domid(h, XS_IS_DOMAIN_INTRODUCED, domid)); +} + /* Only useful for DEBUG versions */ char *xs_debug_command(struct xs_handle *h, const char *cmd, void *data, unsigned int len) diff --git a/tools/xenstore/xs.h b/tools/xenstore/xs.h index 618e6615a6..f59b1e76f9 100644 --- a/tools/xenstore/xs.h +++ b/tools/xenstore/xs.h @@ -140,6 +140,10 @@ bool xs_release_domain(struct xs_handle *h, unsigned int domid); */ char *xs_get_domain_path(struct xs_handle *h, unsigned int domid); +/* Return whether the domain specified has been introduced to xenstored. + */ +bool xs_is_domain_introduced(struct xs_handle *h, unsigned int domid); + /* Only useful for DEBUG versions */ char *xs_debug_command(struct xs_handle *h, const char *cmd, void *data, unsigned int len); diff --git a/xen/include/public/io/xs_wire.h b/xen/include/public/io/xs_wire.h index 88d6b1f212..7d96dc813a 100644 --- a/xen/include/public/io/xs_wire.h +++ b/xen/include/public/io/xs_wire.h @@ -47,6 +47,7 @@ enum xsd_sockmsg_type XS_SET_PERMS, XS_WATCH_EVENT, XS_ERROR, + XS_IS_DOMAIN_INTRODUCED }; #define XS_WRITE_NONE "NONE" -- 2.30.2